<script lang="ts" setup>
import { Ref } from 'vue';
import type { FormInstance } from 'element-plus';
import type { InternalRuleItem } from 'async-validator';
import { QuestionFilled } from '@element-plus/icons-vue';

import Misc from '@core/utils/Misc';
import * as Enums from '@firewall/engine/Enums';
import Order from '@core/engine/Order';
import SubViewContainer from '@core/components/subLayout/SubViewContainer.vue';
import { orderConfirmStore, OrderDetail } from '@firewall/stores/order';
import Firewall, { VpcInstance, SubnetInstance } from '@firewall/engine/Firewall';
import OrderHelper from '@firewall/utils/OrderHelper';

const router = useRouter();
const { t } = useI18n({ inheritLocale: true, useScope: 'local' });

const purchaseDurationMarks = Misc.getIncrementArray(14, 1).reduce((marks, value) => {
  if (value < Enums.MONTHS_PRE_YEAR) {
    marks[value] = t('month', { n: value });
  } else {
    marks[value] = t('year', { n: value - Enums.MONTHS_PRE_YEAR + 1 });
  }
  return marks;
}, {} as Record<number, string>);

const validateFirewallName = (rule: InternalRuleItem, value: string, callback: (error?: string) => void) => {
  const nameReg = /^(?![-0-9])[0-9a-zA-Z-]{2,63}(?<![-])$/;
  if (nameReg.test(value)) {
    callback();
  } else {
    callback(t('firewallNameErrorMessage'));
  }
};
const rules = {
  vpcId: [{ required: true, trigger: 'change', message: t('vpcEmptyMassage') }],
  subnetId: [{ required: true, trigger: 'change', message: t('subnetEmptyMassage') }],
  firewallName: [
    { required: true, trigger: 'blur', message: t('firewallNameEmptyMessage') },
    { validator: validateFirewallName, trigger: 'blur' },
  ],
};

const vpcList: Ref<Array<VpcInstance>> = ref([]);
const subnetList: Ref<Array<SubnetInstance>> = ref([]);
const orderFormRef = ref<FormInstance>();
let cycleCount = 1;
let cycleType = Enums.OrderCycleType.Month;
const orderForm: OrderDetail = reactive({
  vpcId: '',
  firewallName: '',
  firewallEdition: Enums.FirewallEdition.Advanced,
  subnetId: '',
  purchaseDuration: 1,
  protectionIpCount: Enums.ProtectionIpCountSteps[0],
  flowProcessingCapacity: Enums.FlowCapacitySteps[0],
  totalPrice: 0,
  autoRenewStatus: 0,
});

const isQueryingPrice = ref(true);
const fetchTotalPrice = async () => {
  const queryOrder = OrderHelper.buildOrderParams({
    cycleType,
    cycleCount,
    protectionIpCount: orderForm.protectionIpCount,
    flowProcessingCapacity: orderForm.flowProcessingCapacity,
  });
  if (!queryOrder) {
    return;
  }
  isQueryingPrice.value = true;
  try {
    const response = await Order.queryNewPurchaseOrderPrice({ orders: [queryOrder] });
    orderForm.totalPrice = response.totalPrice;
  } finally {
    isQueryingPrice.value = false;
  }
};
const onPurchaseDurationChange = (value: number) => {
  const { type, count } = OrderHelper.getCycleConfig(value);
  cycleType = type;
  cycleCount = count;
  fetchTotalPrice();
};

const fetchVpcList = async () => {
  const response = await Firewall.fetchVpcList();
  vpcList.value = response;
};
const isSubnetListLoading = ref(false);
const fetchSubnetList = async (vpcId: string) => {
  isSubnetListLoading.value = true;
  try {
    const response = await Firewall.fetchSubnetList({ filterNotValid: true, vpcId });
    subnetList.value = response;
  } finally {
    isSubnetListLoading.value = false;
  }
};
const fetchFirewallName = async () => {
  const response = await Firewall.getRandomName();
  orderForm.firewallName = response;
};

const isLoading = ref(false);
onMounted(async () => {
  isLoading.value = true;
  try {
    await Promise.all([
      fetchVpcList(),
      fetchFirewallName(),
      fetchTotalPrice(),
    ]);
  } finally {
    isLoading.value = false;
  }
});

const onVpcChange = async (value: string) => {
  await fetchSubnetList(value);
  orderForm.subnetId = subnetList.value[0].subnetId;
};
const onIpAndFlowCapacityChanged = () => {
  fetchTotalPrice();
};
const onPlaceOrderNow = async (formRef?: FormInstance) => {
  if (!formRef) { return; }
  await formRef.validate();
  const purchaseDurationText = purchaseDurationMarks[orderForm.purchaseDuration];
  const vpcInstance = vpcList.value.find((item) => item.vpcId === orderForm.vpcId);
  orderConfirmStore().update({
    ...orderForm,
    purchaseDurationText,
    vpcIp: vpcInstance?.cidr,
    vpcName: vpcInstance?.name,
  });
  router.push({ name: 'configCenter.quota.purchase.confirm' });
};
</script>
<template>
  <SubViewContainer>
    <ElCard v-loading="isLoading">
      <ElForm ref="orderFormRef"
        :model="orderForm"
        :rules="rules"
        label-width="140px"
        status-icon
        label-position="left"
      >
        <ElFormItem :label="t('vpc')" prop="vpcId">
          <ElSelect v-model="orderForm.vpcId" @change="onVpcChange">
            <ElOption v-for="item in vpcList"
              :key="item.vpcId"
              :label="`${item.name}(${item.cidr})${item.isBuy ? `(${t('vpcHasBoughtFirewall')})` : ''}`"
              :value="item.vpcId"
              :disabled="item.isBuy"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem :label="t('firewallSubnet')" prop="subnetId">
          <ElSelect
            v-model="orderForm.subnetId"
            v-loading="isSubnetListLoading"
            :disabled="subnetList.length === 0"
            :placeholder="subnetList.length === 0 ? t('pleaseSelectOtherVpc') : t('pleaseSelect')"
          >
            <ElOption v-for="item in subnetList"
              :key="item.subnetId"
              :label="`${item.name}(${item.cidr})`"
              :value="item.subnetId"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem :label="t('firewallName')" prop="firewallName">
          <div class="form-item-row">
            <ElInput v-model="orderForm.firewallName" />
            <ElTooltip placement="top">
              <template #content>
                <span v-html="t('firewallNameTip')"/>
              </template>
                <QuestionFilled class="icon-question"/>
            </ElTooltip>
          </div>
        </ElFormItem>
        <ElFormItem :label="t('chooseEdition')" prop="firewallEdition">
          <ElSelect v-model="orderForm.firewallEdition">
            <ElOption
              v-for="edition in Enums.FirewallEdition"
              :key="edition"
              :label="t(`firewallEdition.${edition}`)"
              :value="edition"
            />
          </ElSelect>
        </ElFormItem>
        <IpAndFlowCapacitySlider
          v-model:ipCount='orderForm.protectionIpCount'
          v-model:flowCapacity='orderForm.flowProcessingCapacity'
          @submit="onIpAndFlowCapacityChanged"
        />
        <ElFormItem class="duration-row" :label="t('purchaseDuration')">
          <div class="form-item-row">
            <ElSlider v-model="orderForm.purchaseDuration"
              class="duration-slider"
              :show-tooltip="false"
              :marks="purchaseDurationMarks"
              :min="1"
              :max="14"
              @change="onPurchaseDurationChange"
            />
            <span>{{purchaseDurationMarks[orderForm.purchaseDuration]}}</span>
          </div>
        </ElFormItem>
        <ElFormItem :label="t('autoRenew')">
          <div class="form-item-row">
            <ElCheckbox v-model="orderForm.autoRenewStatus"
              :label="t('enableAutoRenew')"
              :true-label="Enums.RequestBoolean.True"
              :false-label="Enums.RequestBoolean.False"
            />
            <ElTooltip placement="top">
              <template #content>
                <span v-html="t('autoRenewTip')" />
              </template>
              <QuestionFilled class="icon-question"/>
            </ElTooltip>
          </div>
        </ElFormItem>
        <TotalPrice :price="orderForm.totalPrice" :is-loading="isQueryingPrice"/>
      </ElForm>
      <div class="buttons">
        <ElButton type="primary" @click="onPlaceOrderNow(orderFormRef)">{{t('placeOrderNow')}}</ElButton>
        <RouterLink :to="{ name: 'configCenter.quota' }">
          <ElButton>{{t('cancel')}}</ElButton>
        </RouterLink>
      </div>
    </ElCard>
  </SubViewContainer>
</template>

<i18n lang="yaml" locale="zh-CN">
  vpc: '虚拟私有云'
  firewallName: '云防火墙名称'
  vpcHasBoughtFirewall: '已购买'
  firewallSubnet: '云防火墙部署子网'
  pleaseSelectOtherVpc: '无可用子网'
  pleaseSelect: '请选择'
  chooseEdition: '版本选择'
  firewallEdition:
    AdvancedEdition: '高级版'
  defenseIpCountStats: '可防护公网IP数'
  internetFlowProcessingCapacity: '公网流量处理能力'
  purchaseDuration: '购买时长'
  autoRenew: '自动续订'
  enableAutoRenew: '启用自动续订'
  ipCount: '{n} 个'
  month: '{n} 个月'
  year: '{n} 年'
  subnetEmptyMassage: '请选择部署子网'
  vpcEmptyMassage: '请选择虚拟私有云'
  firewallNameEmptyMessage: '请输入防火墙名称'
  firewallNameErrorMessage: '请输入正确的防火墙名称'
  firewallNameTip: '只能由数字、字母、-组成<br/>不能以数字和-开头、以-结尾<br/>长度为2~63字符'
  autoRenewTip: '按月购买:自动续订周期为3个月<br/>按年购买:自动续订周期为1年'
  cancel: '取消'
  placeOrderNow: '立即购买'
</i18n>

<style lang="scss" scoped>
.el-card {
  padding: 20px 30px;
}

.form-item-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  width: 100%;
}

.el-select,
.el-input {
  width: 420px;
}

.duration-row {
  margin-bottom: 40px;
}

.duration-slider {
  width: calc(100% - 160px);
  margin-right: 10px;

  :deep(.el-slider__marks-text) {
    font-size: 12px;
    white-space: nowrap;
  }
}

.icon-question {
  width: 18px;
  height: 18px;
  margin: 0 0 0 20px;
}

.total-price {
  margin-bottom: 20px;
}

.buttons {
  display: flex;
  flex-direction: row;

  .el-button {
    margin-right: 10px;
  }
}
</style>
